
// The definition for an IP header
typedef struct {
 
  uint8_t header[20];
  int totalLength;
  int ttl;
  int protocol;
  short checksum;
  uint8_t srcIP[4];
  uint8_t destIP[4];
  int version;
  int headerLen;

} ipHeader;

// Fills in the fields of the header struct based on the header 
// data in the data array.
void parseIP( ipHeader * h );

// Fills in the fields of the header struct and constructs the header
// given the parameters
void constructIP( ipHeader * h, uint8_t src[4], uint8_t dest[4],
		  uint16_t totalLength, uint8_t ttl, uint8_t protocol) ;


// ICMP Header
typedef struct {
  uint8_t data[8];
  char type;
  char code;
  short checksum;
  short first;
  short second;

} icmpHeader;

// Fills in the fields of the header struct based on the header 
// data in the data array.
void parseICMP( icmpHeader * h );

// Constructs an ICMP error message based on header values
// Call this function via the wrappers (to avoid memorizing codes)
void icmpError( icmpHeader * h ) ;

void icmpPingReply( icmpHeader * h ) ;

void icmpTTLReply ( icmpHeader * h );

void icmpDestinationUnreachable( icmpHeader * h );

void icmpProtocolUnreachable( icmpHeader * h ) ;

void icmpHostUnreachable( icmpHeader * h ) ;


// An ARP Header
typedef struct {

  uint8_t data[28];
  uint8_t senderAddr[6];
  uint8_t senderIP[4];
  uint8_t receiverAddr[6];
  uint8_t receiverIP[4];
  uint16_t operation;

} arpHeader;


void arpResponse( arpHeader * h, 
		  uint8_t srcMac[6], uint8_t destMac[6],
		  uint8_t srcIP[4], uint8_t destIP[4] ) ;

void arpRequest( arpHeader * h, uint8_t srcMac[6],
		 uint8_t srcIP[4], uint8_t destIP[4]) ;

void parseArp( arpHeader * h ) ;


typedef struct {




} ethernetHeader;


